package lesson06;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;


public class Render implements Renderer {
	
	/** Cube instance */
	private Cube cube,cube1,cube2,cube3,cube4;	
	
	/* Rotation values for all axis */
	private float xrot;				//X Rotation ( NEW )
	private float yrot;				//Y Rotation ( NEW )
	private float zrot;				//Z Rotation ( NEW )
	private float intoscreen=-15.0f;
	private float xscreen=-3.0f;
	private float yscreen=-3.0f;
	private float intoscreen1=-15.0f;
	private float xscreen1=-1.0f;
	private float yscreen1=-1.0f;
	private float intoscreen2=-15.0f;
	private float xscreen2=0.0f;
	private float yscreen2=0.0f;
	private float intoscreen3=-15.0f;
	private float xscreen3=1.0f;
	private float yscreen3=1.0f;
	private float intoscreen4=-15.0f;
	private float xscreen4=3.0f;
	private float yscreen4=3.0f;
	private float[] lightAmbient = {0.5f, 0.5f, 0.5f, 1.0f};
	private float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
	private float[] lightPosition = {0.0f, 0.0f, 2.0f, 1.0f};
		
	/* The buffers for our light values ( NEW ) */
	private FloatBuffer lightAmbientBuffer;
	private FloatBuffer lightDiffuseBuffer;
	private FloatBuffer lightPositionBuffer;
	
	
	/** The Activity Context ( NEW ) */
	private Context context;
	
	/**
	 * Instance the Cube object and set 
	 * the Activity Context handed over
	 */
	public Render(Context context) {
		this.context = context;
		ByteBuffer byteBuf = ByteBuffer.allocateDirect(lightAmbient.length * 4);
		byteBuf.order(ByteOrder.nativeOrder());
		lightAmbientBuffer = byteBuf.asFloatBuffer();
		lightAmbientBuffer.put(lightAmbient);
		lightAmbientBuffer.position(0);
		
		byteBuf = ByteBuffer.allocateDirect(lightDiffuse.length * 4);
		byteBuf.order(ByteOrder.nativeOrder());
		lightDiffuseBuffer = byteBuf.asFloatBuffer();
		lightDiffuseBuffer.put(lightDiffuse);
		lightDiffuseBuffer.position(0);
		
		byteBuf = ByteBuffer.allocateDirect(lightPosition.length * 4);
		byteBuf.order(ByteOrder.nativeOrder());
		lightPositionBuffer = byteBuf.asFloatBuffer();
		lightPositionBuffer.put(lightPosition);
		lightPositionBuffer.position(0);
		cube = new Cube();
		cube1 = new Cube();
		cube2 = new Cube();
		cube3 = new Cube();
		cube4 = new Cube();
		
	}

	/**
	 * The Surface is created/init()
	 */
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {		
		
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbientBuffer);		//Setup The Ambient Light ( NEW )
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuseBuffer);		//Setup The Diffuse Light ( NEW )
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer);	//Position The Light ( NEW )
		gl.glEnable(GL10.GL_LIGHT0);
		//Load the texture for the cube once during Surface creation
		cube.loadGLTexture(gl, this.context,1);
	    cube1.loadGLTexture(gl, this.context,2);
		cube2.loadGLTexture(gl, this.context,3);
		cube3.loadGLTexture(gl, this.context,4);
		cube4.loadGLTexture(gl, this.context,5);
		
		gl.glEnable(GL10.GL_TEXTURE_2D);			//Enable Texture Mapping ( NEW )
		gl.glShadeModel(GL10.GL_SMOOTH); 			//Enable Smooth Shading
		gl.glClearColor(0f, 0f, 0f, 0f); 	//Black Background
		gl.glClearDepthf(1.0f); 					//Depth Buffer Setup
		gl.glEnable(GL10.GL_DEPTH_TEST); 			//Enables Depth Testing
		gl.glDepthFunc(GL10.GL_LEQUAL); 			//The Type Of Depth Testing To Do
		
		//Really Nice Perspective Calculations
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
	}

	
	public void onDrawFrame(GL10 gl) {
		
		
		
		//Clear Screen And Depth Buffer
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		gl.glLoadIdentity();					//Reset The Current Modelview Matrix
		gl.glDisable(GL10.GL_LIGHTING);
		
		
		if(intoscreen4>=0f)	
			{
				intoscreen=-15.0f;
				intoscreen1=-15.0f;
				intoscreen2=-15.0f;
				intoscreen3=-20.0f;
				intoscreen4=-25.0f;
						

				xscreen=-3.0f;
				yscreen=-3.0f;
						
				xscreen1=-1.0f;
				yscreen1=-1.0f;
				
				xscreen2=0f;
				yscreen2=0f;
			
			
				xscreen3=1.0f;
				yscreen3=1.0f;
										
				xscreen4=3f;
				yscreen4=3f;
			
		
		
			}  
		else
			{
			
		try {
			Thread.sleep(150);
		} catch (InterruptedException e) {
				e.printStackTrace();
		}
				intoscreen+=0.9f;
				intoscreen1+=0.7f;
				intoscreen2+=0.4f;
				intoscreen3+=0.6f;
				intoscreen4+=0.4f;
			
				xscreen+=0.4;
				yscreen+=0.4;
			
				
				xscreen1+=0.05;
				yscreen1+=0.05;
			
				xscreen2-=0.2;
				yscreen2-=0.2;
				
				xscreen3-=0.2;
				yscreen3-=0.2;
				
				xscreen4-=0.2;
			    yscreen4-=0.2;
			    
			    if(intoscreen3<-13f)
			    {
			    	xscreen3-=0.3;
					yscreen3-=0.3;
					
					xscreen4-=0.6;
				    yscreen4-=0.6;
			    }
			    else
			    {
			    	xscreen3+=0.6;
					yscreen3+=0.6;
					
					xscreen4+=0.5;
				    yscreen4+=0.5;
			    }
			
		}
		
		gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);	//X
		gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);	//Y
		gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);	//Z
		
		gl.glTranslatef(xscreen,yscreen,intoscreen);		//Move 5 units into the screen
		//gl.glScalef(0.8f, 0.8f, 0.8f);
		cube.draw(gl);
			
		gl.glTranslatef(xscreen1,yscreen1,intoscreen1);		//Move 5 units into the screen
		//gl.glScalef(0.8f, 0.8f, 0.8f); //Scale the Cube to 80 percent, otherwise it would be too large for the screen
		cube1.draw(gl);
		
		
		gl.glTranslatef(xscreen2,yscreen2,intoscreen2);		//Move 5 units into the screen
		//gl.glScalef(0.8f, 0.8f, 0.8f); //Scale the Cube to 80 percent, otherwise it would be too large for the screen
		cube2.draw(gl);
		
	    gl.glTranslatef(xscreen3,yscreen3,intoscreen3);		//Move 5 units into the screen
		//gl.glScalef(0.8f, 0.8f, 0.8f);
		cube3.draw(gl);
	 	
		gl.glTranslatef(xscreen4,yscreen4,intoscreen4);		//Move 5 units into the screen
		//gl.glScalef(0.8f, 0.8f, 0.8f);
		cube4.draw(gl);
						
		
	/*	
		gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);	//X
		gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);	//Y
		gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);	//Z
		xrot += 0.3f;
		yrot += 0.2f;
		zrot += 0.5f;	*/
	
	}

	/**
	 * If the surface changes, reset the view
	 */
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		if(height == 0) { 						//Prevent A Divide By Zero By
			height = 1; 						//Making Height Equal One
		}

		gl.glViewport(0, 0, width, height); 	//Reset The Current Viewport
		gl.glMatrixMode(GL10.GL_PROJECTION); 	//Select The Projection Matrix
		gl.glLoadIdentity(); 					//Reset The Projection Matrix

		//Calculate The Aspect Ratio Of The Window
		GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

		gl.glMatrixMode(GL10.GL_MODELVIEW); 	//Select The Modelview Matrix
		gl.glLoadIdentity(); 					//Reset The Modelview Matrix
	}
}
